bitkeeper revision 1.68 (3e53be42OUDyPzjPoKWKLkNgVODyHA)
authorkaf24@labyrinth.cl.cam.ac.uk <kaf24@labyrinth.cl.cam.ac.uk>
Wed, 19 Feb 2003 17:26:26 +0000 (17:26 +0000)
committerkaf24@labyrinth.cl.cam.ac.uk <kaf24@labyrinth.cl.cam.ac.uk>
Wed, 19 Feb 2003 17:26:26 +0000 (17:26 +0000)
Many files:
  Big changes to blkdev layer -- rings now allocated in hypervisor space.

xen-2.4.16/common/domain.c
xen-2.4.16/common/event.c
xen-2.4.16/drivers/block/xen_block.c
xen-2.4.16/include/hypervisor-ifs/block.h
xen-2.4.16/include/hypervisor-ifs/hypervisor-if.h
xen-2.4.16/include/hypervisor-ifs/network.h
xen-2.4.16/include/xeno/sched.h
xenolinux-2.4.16-sparse/arch/xeno/drivers/block/xl_block.c
xenolinux-2.4.16-sparse/arch/xeno/drivers/block/xl_block_test.c
xenolinux-2.4.16-sparse/arch/xeno/mm/init.c
xenolinux-2.4.16-sparse/include/asm-xeno/pgtable.h

index 9e5f3dd8b88df708c4e221242559ea06998a0d52..4a9a8a83594668f682d978964c0a18e34e822af1 100644 (file)
@@ -42,10 +42,17 @@ struct task_struct *do_newdomain(unsigned int dom_id, unsigned int cpu)
     p->domain    = dom_id;
     p->processor = cpu;
 
+    spin_lock_init(&p->blk_ring_lock);
+
     p->shared_info = (void *)get_free_page(GFP_KERNEL);
     memset(p->shared_info, 0, PAGE_SIZE);
     SHARE_PFN_WITH_DOMAIN(virt_to_page(p->shared_info), dom_id);
 
+    if ( sizeof(*p->blk_ring_base) > PAGE_SIZE ) BUG();
+    p->blk_ring_base = (blk_ring_t *)get_free_page(GFP_KERNEL);
+    memset(p->blk_ring_base, 0, PAGE_SIZE);
+    SHARE_PFN_WITH_DOMAIN(virt_to_page(p->blk_ring_base), dom_id);
+
     SET_GDT_ENTRIES(p, DEFAULT_GDT_ENTRIES);
     SET_GDT_ADDRESS(p, DEFAULT_GDT_ADDRESS);
 
@@ -54,16 +61,7 @@ struct task_struct *do_newdomain(unsigned int dom_id, unsigned int cpu)
     p->active_mm  = &p->mm;
     p->num_net_vifs = 0;
 
-    INIT_LIST_HEAD(&p->io_done_queue);
-    spin_lock_init(&p->io_done_queue_lock);
-
-    /*
-     * KAF: Passing in newdomain struct to this function is gross!
-     * Therefore, for now we just allocate the single blk_ring
-     * before the multiople net_rings :-)
-     */
-    p->blk_ring_base = (blk_ring_t *)(p->shared_info + 1);
-    p->net_ring_base = (net_ring_t *)(p->blk_ring_base + 1);
+    p->net_ring_base = (net_ring_t *)(p->shared_info + 1);
     INIT_LIST_HEAD(&p->pg_head);
     p->tot_pages = 0;
     write_lock_irqsave(&tasklist_lock, flags);
@@ -218,6 +216,9 @@ void release_task(struct task_struct *p)
     }
     if ( p->mm.perdomain_pt ) free_page((unsigned long)p->mm.perdomain_pt);
 
+    UNSHARE_PFN(virt_to_page(p->blk_ring_base));
+    free_page((unsigned long)p->blk_ring_base);
+
     UNSHARE_PFN(virt_to_page(p->shared_info));
     free_page((unsigned long)p->shared_info);
 
@@ -316,7 +317,7 @@ int final_setup_guestos(struct task_struct * p, dom_meminfo_t * meminfo)
     virt_startinfo_addr->num_net_rings = p->num_net_vifs;
 
     /* Add block io interface */
-    virt_startinfo_addr->blk_ring = (blk_ring_t *)SH2G(p->blk_ring_base);
+    virt_startinfo_addr->blk_ring = virt_to_phys(p->blk_ring_base);
 
     /* Copy the command line */
     strcpy(virt_startinfo_addr->cmd_line, meminfo->cmd_line);
@@ -548,9 +549,7 @@ int setup_guestos(struct task_struct *p, dom0_newdomain_t *params)
     virt_startinfo_address->num_net_rings = p->num_net_vifs;
 
     /* Add block io interface */
-    virt_startinfo_address->blk_ring = 
-       (blk_ring_t *)SHIP2GUEST(p->blk_ring_base); 
-
+    virt_startinfo_address->blk_ring = virt_to_phys(p->blk_ring_base); 
 
     /* We tell OS about any modules we were given. */
     if ( nr_mods > 1 )
index 4cc2c70287efd8708eb3afd39a7691fd09cb4e34..27748064434753fb2e792b58831f79b9ac6b710e 100644 (file)
@@ -14,7 +14,6 @@
 typedef void (*hyp_event_callback_fn_t)(void);
 
 extern void schedule(void);
-extern void flush_blk_queue(void);
 extern void update_shared_ring(void);
 
 /* Ordering must match definitions of _HYP_EVENT_* in xeno/sched.h */
@@ -23,7 +22,6 @@ static hyp_event_callback_fn_t event_call_fn[] =
     schedule,
     update_shared_ring,
     kill_domain, 
-    flush_blk_queue
 };
 
 /* Handle outstanding events for the currently-executing domain. */
index fa3833d03a88816aa9cd7098059a878ac5f3ec6b..8e70eff572d49128a24429bfebed573060b762c8 100644 (file)
@@ -34,12 +34,12 @@ typedef struct blk_request
 {
   struct list_head queue;
   struct buffer_head *bh;
-  blk_ring_entry_t request;
-  struct task_struct *domain;                           /* requesting domain */
+  blk_ring_req_entry_t *request;
+  struct task_struct *domain;                /* requesting domain */
 } blk_request_t;
 #define MAX_PENDING_REQS 256                 /* very arbitrary */
 static kmem_cache_t *blk_request_cachep;
-static atomic_t nr_pending, nr_done;
+static atomic_t nr_pending;
 static int pending_work;              /* which domains have work for us? */
 
 
@@ -62,10 +62,12 @@ int dispatch_debug_block_io (int index);
 void end_block_io_op(struct buffer_head * bh)
 {
     unsigned long cpu_mask;
-    /* struct list_head *list;*/
     blk_request_t *blk_request = NULL;
-    unsigned long flags; /* irq save */
+    unsigned long flags;
     struct task_struct *p;
+    int position = 0;
+    blk_ring_t *blk_ring;
+    int loop;
 
     if (XEN_BLK_DEBUG)  
        printk(XEN_BLK_DEBUG_LEVEL "XEN end_block_io_op,  bh: %lx\n",
@@ -77,76 +79,24 @@ void end_block_io_op(struct buffer_head * bh)
     
     p = blk_request->domain;
 
-    atomic_inc(&nr_done);
-    spin_lock_irqsave(&p->io_done_queue_lock, flags);
-    list_add_tail(&blk_request->queue, &p->io_done_queue);
-    /* enqueue work for 'flush_blk_queue' handler */
-    cpu_mask = mark_hyp_event(p, _HYP_EVENT_BLK_RX);
-    spin_unlock_irqrestore(&p->io_done_queue_lock, flags);
-    
-    /* now kick the hypervisor */
-    hyp_event_notify(cpu_mask); 
-    return;
-
- bad_interrupt:
-    printk (KERN_ALERT
-            "   block io interrupt received for unknown buffer [0x%lx]\n",
-            (unsigned long) bh);
-    BUG();
-    return;
-}
-
-/*
- * flush_blk_queue
- *
- * Called by the hypervisor synchronously when there is something to do
- * (block transfers have completed)
- */
-
-void flush_blk_queue(void)
-{
-    struct task_struct *p = current;
-    blk_request_t *blk_request;
-    int position = 0;
-    blk_ring_t *blk_ring;
-    unsigned long flags;
-    int loop;
+    /* Place on the response ring for the relevant domain. */ 
+    spin_lock_irqsave(&p->blk_ring_lock, flags);
+    blk_ring = p->blk_ring_base;
+    position = blk_ring->resp_prod;
+    blk_ring->resp_ring[position].id     = blk_request->request->id;
+    blk_ring->resp_ring[position].status = 0;
+    blk_ring->resp_prod = BLK_RESP_RING_INC(blk_ring->resp_prod);
+    spin_unlock_irqrestore(&p->blk_ring_lock, flags);
     
-    spin_lock_irqsave(&p->io_done_queue_lock, flags);
-    clear_bit(_HYP_EVENT_BLK_RX, &p->hyp_events);
+    /* Kick the relevant domain. */
+    cpu_mask = mark_guest_event(p, _EVENT_BLK_RESP);
+    guest_event_notify(cpu_mask); 
+
+    /* Free state associated with this request. */
+    if ( blk_request->bh ) 
+        kfree(blk_request->bh);     
+    kmem_cache_free(blk_request_cachep, blk_request);
     
-    while ( !list_empty(&p->io_done_queue) )
-    {
-       blk_request = list_entry(p->io_done_queue.next, blk_request_t, queue);
-       list_del(&blk_request->queue);
-       spin_unlock_irqrestore(&p->io_done_queue_lock, flags);
-       atomic_dec(&nr_done);
-
-       /* place on ring for guest os */ 
-       blk_ring = p->blk_ring_base;
-       position = blk_ring->brx_prod;
-
-       if (XEN_BLK_DEBUG)  
-           printk(XEN_BLK_DEBUG_LEVEL "XEN flush_blk_queue [%d]\n", position);
-
-       memcpy(&blk_ring->brx_ring[position], &blk_request->request,
-              sizeof(blk_ring_entry_t));
-       blk_ring->brx_prod = BLK_RX_RING_INC(blk_ring->brx_prod);
-
-       /* notify appropriate guest os */
-       set_bit(_EVENT_BLK_RX, &p->shared_info->events);
-       
-       /* free the buffer header allocated in do_block_io_op */
-       if ( blk_request->bh )
-           kfree(blk_request->bh); 
-
-        kmem_cache_free(blk_request_cachep, blk_request);
-
-       spin_lock_irqsave(&p->io_done_queue_lock, flags);
-    }
-    spin_unlock_irqrestore(&p->io_done_queue_lock, flags);
-
-
     /* XXX SMH: below is ugly and dangerous -- fix */
     /*
      * now check if there is any pending work from any domain
@@ -177,7 +127,14 @@ void flush_blk_queue(void)
        }
     }
 
-    return; 
+    return;
+
+ bad_interrupt:
+    printk (KERN_ALERT
+            "   block io interrupt received for unknown buffer [0x%lx]\n",
+            (unsigned long) bh);
+    BUG();
+    return;
 }
 
 
@@ -206,15 +163,15 @@ long do_block_io_op_domain (struct task_struct* task)
 
     if (XEN_BLK_DEBUG)  
        printk(XEN_BLK_DEBUG_LEVEL "XEN do_block_io_op %d %d\n",
-              blk_ring->btx_cons, blk_ring->btx_prod);
-
-    for (loop = blk_ring->btx_cons; 
-        loop != blk_ring->btx_prod; 
-        loop = BLK_TX_RING_INC(loop)) {
+              blk_ring->req_cons, blk_ring->req_prod);
 
+    for ( loop = blk_ring->req_cons; 
+         loop != blk_ring->req_prod; 
+         loop = BLK_REQ_RING_INC(loop) ) 
+    {
        status = 1;
 
-       switch (blk_ring->btx_ring[loop].operation) {
+       switch (blk_ring->req_ring[loop].operation) {
 
        case XEN_BLOCK_READ:
        case XEN_BLOCK_WRITE:
@@ -231,7 +188,7 @@ long do_block_io_op_domain (struct task_struct* task)
 
        default:
            printk (KERN_ALERT "error: unknown block io operation [%d]\n",
-                   blk_ring->btx_ring[loop].operation);
+                   blk_ring->req_ring[loop].operation);
            BUG();
        }
 
@@ -247,7 +204,7 @@ long do_block_io_op_domain (struct task_struct* task)
        }
     }
 
-    blk_ring->btx_cons = loop;
+    blk_ring->req_cons = loop;
     return 0L;
 }
 
@@ -265,14 +222,13 @@ int dispatch_probe_block_io (int index)
     blk_ring_t *blk_ring = current->blk_ring_base;
     xen_disk_info_t *xdi;
     
-    xdi = phys_to_virt((unsigned long)blk_ring->btx_ring[index].buffer);
+    xdi = phys_to_virt((unsigned long)blk_ring->req_ring[index].buffer);
     
     ide_probe_devices(xdi);
-    
-    memcpy(&blk_ring->brx_ring[blk_ring->brx_prod], 
-          &blk_ring->btx_ring[index], 
-          sizeof(blk_ring_entry_t));
-    blk_ring->brx_prod = BLK_RX_RING_INC(blk_ring->brx_prod);
+
+    blk_ring->resp_ring[blk_ring->resp_prod].id = blk_ring->req_ring[index].id;
+    blk_ring->resp_ring[blk_ring->resp_prod].status = 0;
+    blk_ring->resp_prod = BLK_RESP_RING_INC(blk_ring->resp_prod);
     
     return 0;
 }
@@ -291,24 +247,24 @@ int dispatch_rw_block_io (int index)
      * check to make sure that the block request seems at least
      * a bit legitimate
      */
-    if ((blk_ring->btx_ring[index].block_size & (0x200 - 1)) != 0) {
+    if ((blk_ring->req_ring[index].block_size & (0x200 - 1)) != 0) {
        printk(KERN_ALERT "    error: dodgy block size: %d\n", 
-              blk_ring->btx_ring[index].block_size);
+              blk_ring->req_ring[index].block_size);
        BUG();
     }
     
-    if(blk_ring->btx_ring[index].buffer == NULL) { 
+    if(blk_ring->req_ring[index].buffer == NULL) { 
        printk(KERN_ALERT "xen_block: bogus buffer from guestOS\n"); 
        BUG();
     }
 
     if (XEN_BLK_DEBUG) {
-       printk(XEN_BLK_DEBUG_LEVEL "    btx_cons: %d  btx_prod %d  index: %d "
-              "op: %s, pri: %s\n", blk_ring->btx_cons, blk_ring->btx_prod, 
+       printk(XEN_BLK_DEBUG_LEVEL "    req_cons: %d  req_prod %d  index: %d "
+              "op: %s, pri: %s\n", blk_ring->req_cons, blk_ring->req_prod, 
               index, 
-              (blk_ring->btx_ring[index].operation == XEN_BLOCK_READ ? 
+              (blk_ring->req_ring[index].operation == XEN_BLOCK_READ ? 
                "read" : "write"), 
-              (blk_ring->btx_ring[index].priority == XEN_BLOCK_SYNC ? 
+              (blk_ring->req_ring[index].priority == XEN_BLOCK_SYNC ? 
                "sync" : "async"));
     }
 
@@ -319,7 +275,6 @@ int dispatch_rw_block_io (int index)
     blk_request = kmem_cache_alloc(blk_request_cachep, GFP_ATOMIC);
 
     /* we'll be doing this frequently, would a cache be appropriate? */
-    /* free in flush_blk_queue */
     bh = (struct buffer_head *) kmalloc(sizeof(struct buffer_head), 
                                        GFP_KERNEL);
     if (!bh) {
@@ -330,16 +285,16 @@ int dispatch_rw_block_io (int index)
     /* set just the important bits of the buffer header */
     memset (bh, 0, sizeof (struct buffer_head));
     
-    bh->b_blocknr       = blk_ring->btx_ring[index].block_number;
-    bh->b_size          = blk_ring->btx_ring[index].block_size; 
-    bh->b_dev           = blk_ring->btx_ring[index].device; 
-    bh->b_rsector       = blk_ring->btx_ring[index].sector_number;
+    bh->b_blocknr       = blk_ring->req_ring[index].block_number;
+    bh->b_size          = blk_ring->req_ring[index].block_size; 
+    bh->b_dev           = blk_ring->req_ring[index].device; 
+    bh->b_rsector       = blk_ring->req_ring[index].sector_number;
     bh->b_data          = phys_to_virt((unsigned long)
-                                      blk_ring->btx_ring[index].buffer);
+                                      blk_ring->req_ring[index].buffer);
     bh->b_count.counter = 1;
     bh->b_xen_request   = (void *)blk_request;  
     
-    if (blk_ring->btx_ring[index].operation == XEN_BLOCK_WRITE) {
+    if (blk_ring->req_ring[index].operation == XEN_BLOCK_WRITE) {
        bh->b_state = ((1 << BH_JBD) | (1 << BH_Mapped) | (1 << BH_Req) |
                       (1 << BH_Dirty) | (1 << BH_Uptodate));
        operation = WRITE;
@@ -348,9 +303,8 @@ int dispatch_rw_block_io (int index)
        operation = READ;
     }
 
-    /* save meta data about request XXX SMH: should copy_from_user() */
-    memcpy(&blk_request->request,
-          &blk_ring->btx_ring[index], sizeof(blk_ring_entry_t));
+    /* save meta data about request */
+    blk_request->request = &blk_ring->req_ring[index];
     blk_request->bh     = bh;
     blk_request->domain = current; 
     
@@ -400,9 +354,8 @@ void dump_queue_head(struct list_head *queue, char *name)
 
 static void dump_blockq(u_char key, void *dev_id, struct pt_regs *regs) 
 {
-    printk("Dumping block queue stats:\n"); 
-    printk("nr_pending = %d, nr_done = %d\n",
-           atomic_read(&nr_pending), atomic_read(&nr_done));
+    printk("Dumping block queue stats: nr_pending = %d\n",
+           atomic_read(&nr_pending));
 }
 
 
@@ -422,6 +375,8 @@ void initialize_block_io ()
     
     /* If bit i is true then domain i has work for us to do. */
     pending_work = 0;
+
+    atomic_set(&nr_pending, 0);
 }
 
 
index 76db90da1a85339449aa9b07d68a218e3b5b04d7..1bf198e1963c4a0ca93e46297142cf205e4de858 100644 (file)
 
 #define XEN_BLOCK_MAX_DOMAINS 32  /* NOTE: FIX THIS. VALUE SHOULD COME FROM? */
 
-#define BLK_TX_RING_SIZE 256
-#define BLK_RX_RING_SIZE 256
+#define BLK_REQ_RING_SIZE  64
+#define BLK_RESP_RING_SIZE 64
 
-#define BLK_TX_RING_MAX_ENTRIES (BLK_TX_RING_SIZE - 2)
-#define BLK_RX_RING_MAX_ENTRIES (BLK_RX_RING_SIZE - 2)
+#define BLK_REQ_RING_MAX_ENTRIES  (BLK_REQ_RING_SIZE - 2)
+#define BLK_RESP_RING_MAX_ENTRIES (BLK_RESP_RING_SIZE - 2)
 
-#define BLK_TX_RING_INC(_i)    (((_i)+1) & (BLK_TX_RING_SIZE-1))
-#define BLK_RX_RING_INC(_i)    (((_i)+1) & (BLK_RX_RING_SIZE-1))
-#define BLK_TX_RING_ADD(_i,_j) (((_i)+(_j)) & (BLK_TX_RING_SIZE-1))
-#define BLK_RX_RING_ADD(_i,_j) (((_i)+(_j)) & (BLK_RX_RING_SIZE-1))
+#define BLK_REQ_RING_INC(_i)     (((_i)+1) & (BLK_REQ_RING_SIZE-1))
+#define BLK_RESP_RING_INC(_i)    (((_i)+1) & (BLK_RESP_RING_SIZE-1))
+#define BLK_REQ_RING_ADD(_i,_j)  (((_i)+(_j)) & (BLK_REQ_RING_SIZE-1))
+#define BLK_RESP_RING_ADD(_i,_j) (((_i)+(_j)) & (BLK_RESP_RING_SIZE-1))
 
-typedef struct blk_ring_entry 
+typedef struct blk_ring_req_entry 
 {
-  void *          id;                   /* for guest os use; used for the bh */
-  int             priority;         /* orig sched pri, SYNC or ASYNC for now */
-  int             operation;            /* XEN_BLOCK_READ or XEN_BLOCK_WRITE */
-  char *          buffer;
-  unsigned long   block_number;                              /* block number */
-  unsigned short  block_size;                                  /* block size */
-  kdev_t          device;
-  unsigned long   sector_number;             /* real buffer location on disk */
-} blk_ring_entry_t;
+    void *          id;                /* for guest os use */
+    int             priority;          /* SYNC or ASYNC for now */
+    int             operation;         /* XEN_BLOCK_READ or XEN_BLOCK_WRITE */
+    char *          buffer;
+    unsigned long   block_number;      /* block number */
+    unsigned short  block_size;        /* block size */
+    kdev_t          device;
+    unsigned long   sector_number;     /* real buffer location on disk */
+} blk_ring_req_entry_t;
+
+typedef struct blk_ring_resp_entry
+{
+    void *id;
+    unsigned long status;
+} blk_ring_resp_entry_t;
 
 typedef struct blk_ring_st 
 {
-  blk_ring_entry_t *btx_ring;
-  unsigned int      btx_prod, btx_cons;
-  unsigned int             btx_ring_size;
-
-  blk_ring_entry_t *brx_ring;
-  unsigned int      brx_prod, brx_cons;
-  unsigned int     brx_ring_size;
+  unsigned int      req_prod, req_cons;
+  unsigned int      resp_prod, resp_cons;
+  blk_ring_req_entry_t  req_ring[BLK_REQ_RING_SIZE];
+  blk_ring_resp_entry_t resp_ring[BLK_RESP_RING_SIZE];
 } blk_ring_t;
 
 #define MAX_XEN_DISK_COUNT 100
index cf3edb8cfb8862b71e89e78febdfc72b14e1e389..6ecac5848edc7fa203743d37e894d63d6ae39768 100644 (file)
@@ -103,22 +103,20 @@ typedef struct
  */
 
 /* Events that a guest OS may receive from the hypervisor. */
-#define EVENT_BLK_TX   0x01 /* packets for transmission. */
-#define EVENT_BLK_RX   0x02 /* empty buffers for receive. */
-#define EVENT_TIMER    0x04 /* a timeout has been updated. */
-#define EVENT_DIE      0x08 /* OS is about to be killed. Clean up please! */
-#define EVENT_DEBUG    0x10 /* request guest to dump debug info (gross!) */
-#define EVENT_NET_TX   0x20 /* packets for transmission. */
-#define EVENT_NET_RX   0x40 /* empty buffers for receive. */
+#define EVENT_BLK_RESP 0x01 /* A block device response has been queued. */
+#define EVENT_TIMER    0x02 /* A timeout has been updated. */
+#define EVENT_DIE      0x04 /* OS is about to be killed. Clean up please! */
+#define EVENT_DEBUG    0x08 /* Request guest to dump debug info (gross!) */
+#define EVENT_NET_TX   0x10 /* There are packets for transmission. */
+#define EVENT_NET_RX   0x20 /* There are empty buffers for receive. */
 
 /* Bit offsets, as opposed to the above masks. */
-#define _EVENT_BLK_TX  0
-#define _EVENT_BLK_RX  1
-#define _EVENT_TIMER   2
-#define _EVENT_DIE     3
-#define _EVENT_NET_TX  4
-#define _EVENT_NET_RX  5
-#define _EVENT_DEBUG   6
+#define _EVENT_BLK_RESP 0
+#define _EVENT_TIMER    1
+#define _EVENT_DIE      2
+#define _EVENT_NET_TX   3
+#define _EVENT_NET_RX   4
+#define _EVENT_DEBUG    5
 
 
 /*
@@ -195,13 +193,13 @@ typedef struct shared_info_st {
  */
 typedef struct start_info_st {
     unsigned long nr_pages;       /* total pages allocated to this domain */
-    shared_info_t *shared_info;   /* start address of shared info struct */
+    shared_info_t *shared_info;   /* VIRTUAL address of shared info struct */
     unsigned long  pt_base;       /* VIRTUAL address of page directory */
-    unsigned long mod_start;      /* start address of pre-loaded module */
+    unsigned long mod_start;      /* VIRTUAL address of pre-loaded module */
     unsigned long mod_len;        /* size (bytes) of pre-loaded module */
-    net_ring_t *net_rings;
+    net_ring_t *net_rings;        /* network rings (VIRTUAL ADDRESS) */
     int num_net_rings;
-    blk_ring_t *blk_ring;         /* block io communication rings */
+    unsigned long blk_ring;       /* block io ring (MACHINE ADDRESS) */
     unsigned char cmd_line[1];    /* variable-length */
 } start_info_t;
 
index f3f13dc77b8fb219fe97deeff93b9c137be0fdfd..6f528fcf63f5f59b4d705079ed2297e05d42a734 100644 (file)
@@ -39,7 +39,7 @@ typedef struct net_ring_st {
      */
     tx_entry_t *tx_ring;
     unsigned int tx_prod, tx_cons, tx_event;
-    unsigned int tx_ring_size;
+
     /*
      * Guest OS places empty buffers into ring at rx_prod.
      * Hypervisor fills buffers as rx_cons.
@@ -50,11 +50,10 @@ typedef struct net_ring_st {
      */
     rx_entry_t *rx_ring;
     unsigned int rx_prod, rx_cons, rx_event;
-    unsigned int rx_ring_size;
 } net_ring_t;
 
 /* Specify base of per-domain array. Get returned free slot in the array. */
-//net_ring_t *create_net_vif(int domain);
+/*net_ring_t *create_net_vif(int domain);*/
 
 /* Packet routing/filtering code follows:
  */
index ec65902fef7dd661d7fdb46528df3bfc29785fde..a02c28ff2299c0583bab039a96170ebbcca66534 100644 (file)
@@ -48,7 +48,6 @@ extern struct mm_struct init_mm;
 #define _HYP_EVENT_NEED_RESCHED 0
 #define _HYP_EVENT_NET_RX       1
 #define _HYP_EVENT_DIE          2
-#define _HYP_EVENT_BLK_RX       3
 
 #define PF_DONEFPUINIT  0x1  /* Has the FPU been initialised for this task? */
 #define PF_USEDFPU      0x2  /* Has this task used the FPU since last save? */
@@ -77,8 +76,7 @@ struct task_struct {
 
     /* Block I/O */
     blk_ring_t *blk_ring_base;
-    struct list_head io_done_queue;
-    spinlock_t io_done_queue_lock;
+    spinlock_t blk_ring_lock;
 
     int has_cpu, policy, counter;
 
index f7bd088ff41a63f0f7da1d85c53483d32f7c296b..e9f1aed53c1c00f09831e64db4af79be8a91108f 100644 (file)
@@ -40,8 +40,7 @@ static int xlblk_read_ahead;
 static int xlblk_hardsect_size[XLBLK_MAX];
 static int xlblk_max_sectors[XLBLK_MAX];
 
-#define XLBLK_RX_IRQ _EVENT_BLK_RX
-#define XLBLK_TX_IRQ _EVENT_BLK_TX
+#define XLBLK_RESPONSE_IRQ _EVENT_BLK_RESP
 
 #define DEBUG_IRQ    _EVENT_DEBUG 
 
@@ -56,6 +55,8 @@ xlblk_device_t xlblk_device;
 #define XLBLK_DEBUG       0
 #define XLBLK_DEBUG_IOCTL 0
 
+static blk_ring_t *blk_ring;
+
 /* 
  * disk management
  */
@@ -203,7 +204,6 @@ void hypervisor_request(void *         id,
                        kdev_t         device,
                        int            mode)
 {
-    blk_ring_t *blk_ring = start_info.blk_ring;
     int position;
     void *buffer_pa, *buffer_ma; 
     kdev_t phys_device = (kdev_t) 0;
@@ -246,24 +246,24 @@ void hypervisor_request(void *         id,
     }
 
 
-    if (BLK_TX_RING_INC(blk_ring->btx_prod) == blk_ring->btx_cons) {
-       printk (KERN_ALERT "hypervisor_request: btx_cons: %d, btx_prod:%d",
-               blk_ring->btx_cons, blk_ring->btx_prod);
+    if (BLK_REQ_RING_INC(blk_ring->req_prod) == blk_ring->req_cons) {
+       printk (KERN_ALERT "hypervisor_request: req_cons: %d, req_prod:%d",
+               blk_ring->req_cons, blk_ring->req_prod);
        BUG(); 
     }
     
     /* Fill out a communications ring structure & trap to the hypervisor */
-    position = blk_ring->btx_prod;
-    blk_ring->btx_ring[position].id            = id;
-    blk_ring->btx_ring[position].priority      = mode;
-    blk_ring->btx_ring[position].operation     = operation;
-    blk_ring->btx_ring[position].buffer        = buffer_ma;
-    blk_ring->btx_ring[position].block_number  = block_number;
-    blk_ring->btx_ring[position].block_size    = block_size;
-    blk_ring->btx_ring[position].device        = phys_device;
-    blk_ring->btx_ring[position].sector_number = sector_number;
-
-    blk_ring->btx_prod = BLK_TX_RING_INC(blk_ring->btx_prod);
+    position = blk_ring->req_prod;
+    blk_ring->req_ring[position].id            = id;
+    blk_ring->req_ring[position].priority      = mode;
+    blk_ring->req_ring[position].operation     = operation;
+    blk_ring->req_ring[position].buffer        = buffer_ma;
+    blk_ring->req_ring[position].block_number  = block_number;
+    blk_ring->req_ring[position].block_size    = block_size;
+    blk_ring->req_ring[position].device        = phys_device;
+    blk_ring->req_ring[position].sector_number = sector_number;
+
+    blk_ring->req_prod = BLK_REQ_RING_INC(blk_ring->req_prod);
 
     switch(mode) { 
 
@@ -325,20 +325,16 @@ static void do_xlblk_request (request_queue_t *rq)
        /* is there space in the tx ring for this request?
         * if the ring is full, then leave the request in the queue
         *
-        * THIS IS A BIT BOGUS SINCE XEN COULD BE UPDATING BTX_CONS
+        * THIS IS A BIT BOGUS SINCE XEN COULD BE UPDATING REQ_CONS
         * AT THE SAME TIME
         */
-       {
-           blk_ring_t *blk_ring = start_info.blk_ring;
-           
-           if (BLK_RX_RING_INC(blk_ring->btx_prod) == blk_ring->btx_cons)
-           {
-               printk (KERN_ALERT "OOPS, TX LOOKS FULL  cons: %d  prod: %d\n",
-                       blk_ring->btx_cons, blk_ring->btx_prod);
-               BUG(); 
-               break;
-           }
-       }
+        if (BLK_RESP_RING_INC(blk_ring->req_prod) == blk_ring->req_cons)
+        {
+            printk (KERN_ALERT "OOPS, TX LOOKS FULL  cons: %d  prod: %d\n",
+                    blk_ring->req_cons, blk_ring->req_prod);
+            BUG(); 
+            break;
+        }
        
        req->errors = 0;
        blkdev_dequeue_request(req);
@@ -382,24 +378,22 @@ static struct block_device_operations xenolinux_block_fops =
     revalidate:         xenolinux_block_revalidate,
 };
 
-static void xlblk_rx_int(int irq, void *dev_id, struct pt_regs *ptregs)
+static void xlblk_response_int(int irq, void *dev_id, struct pt_regs *ptregs)
 {
-    blk_ring_t *blk_ring = start_info.blk_ring;
     struct request *req;
     int loop;
     u_long flags; 
     
-    for (loop = blk_ring->brx_cons;
-        loop != blk_ring->brx_prod;
-        loop = BLK_RX_RING_INC(loop)) {
+    for (loop = blk_ring->resp_cons;
+        loop != blk_ring->resp_prod;
+        loop = BLK_RESP_RING_INC(loop)) {
 
-       blk_ring_entry_t *bret = &blk_ring->brx_ring[loop];
+       blk_ring_resp_entry_t *bret = &blk_ring->resp_ring[loop];
        
-       if(bret->operation == XEN_BLOCK_PROBE)
-           continue; 
+       req = (struct request *)bret->id;
+        if ( req == NULL ) continue; /* probes have NULL id */
 
        spin_lock_irqsave(&io_request_lock, flags);
-       req = (struct request *)bret->id;
            
        if (!end_that_request_first(req, 1, "XenBlk"))
            end_that_request_last(req);
@@ -407,54 +401,27 @@ static void xlblk_rx_int(int irq, void *dev_id, struct pt_regs *ptregs)
        
     }
     
-    blk_ring->brx_cons = loop;
+    blk_ring->resp_cons = loop;
 }
 
-static void xlblk_tx_int(int irq, void *dev_id, struct pt_regs *ptregs)
-{
-    if (XLBLK_DEBUG) 
-       printk (KERN_ALERT "--- xlblock::xlblk_tx_int\n"); 
-}
 
 int __init xlblk_init(void)
 {
-    blk_ring_t *blk_ring = start_info.blk_ring;
     int loop, error, result;
 
-    /* initialize memory rings to communicate with hypervisor */
-    if ( blk_ring == NULL ) return -ENOMEM;
+    /* This mapping was created early at boot time. */
+    blk_ring = (blk_ring_t *)FIX_BLKRING_BASE;
 
-    blk_ring->btx_prod = blk_ring->btx_cons = 0;
-    blk_ring->brx_prod = blk_ring->brx_cons = 0;
-    blk_ring->btx_ring = NULL;
-    blk_ring->brx_ring = NULL;
-    
-    blk_ring->btx_ring = kmalloc(BLK_TX_RING_SIZE * sizeof(blk_ring_entry_t),
-                                GFP_KERNEL);
-    blk_ring->brx_ring = kmalloc(BLK_RX_RING_SIZE * sizeof(blk_ring_entry_t),
-                                GFP_KERNEL);
-
-    if ((blk_ring->btx_ring == NULL) || (blk_ring->brx_ring == NULL)) {
-       printk (KERN_ALERT "could not alloc ring memory for block device\n");
-       error = -ENOBUFS;
-       goto fail;
-    }
+    blk_ring->req_prod = blk_ring->req_cons = 0;
+    blk_ring->resp_prod = blk_ring->resp_cons = 0;
     
-    error = request_irq(XLBLK_RX_IRQ, xlblk_rx_int, 0, 
-                       "xlblk-rx", &xlblk_device);
+    error = request_irq(XLBLK_RESPONSE_IRQ, xlblk_response_int, 0, 
+                       "xlblk-response", &xlblk_device);
     if (error) {
        printk(KERN_ALERT "Could not allocate receive interrupt\n");
        goto fail;
     }
 
-    error = request_irq(XLBLK_TX_IRQ, xlblk_tx_int, 0, 
-                       "xlblk-tx", &xlblk_device);
-    if (error) {
-       printk(KERN_ALERT "Could not allocate transmit interrupt\n");
-       free_irq(XLBLK_RX_IRQ, &xlblk_device);
-       goto fail;
-    }
-
     memset (&xen_disk_info, 0, sizeof(xen_disk_info));
     xen_disk_info.count = 0;
 
@@ -505,8 +472,6 @@ int __init xlblk_init(void)
     return 0;
 
  fail:
-    if (blk_ring->btx_ring) kfree(blk_ring->btx_ring);
-    if (blk_ring->brx_ring) kfree(blk_ring->brx_ring);
     return error;
 }
 
index cab6d9a330a904f09076b045a4436773fc4d7047..4d09a10409a24bd6b70be4a5edc993d78bd174c9 100644 (file)
@@ -22,7 +22,7 @@
 /******************************************************************/
 
 static struct proc_dir_entry *bdt;
-static blk_ring_entry_t meta;
+static blk_ring_req_entry_t meta;
 static char * data;
 
 static int proc_read_bdt(char *page, char **start, off_t off,
index b1e75a6bcfaf3088ad4c0487b3ba4e4c3f7f66ff..ac2019910e9aab7905e900782fb3b71d544725ae 100644 (file)
@@ -115,7 +115,9 @@ static inline void set_pte_phys (unsigned long vaddr,
     if (pte_val(*pte))
         pte_ERROR(*pte);
     pgprot_val(prot) = pgprot_val(PAGE_KERNEL) | pgprot_val(flags);
-    set_pte(pte, mk_pte_phys(phys, prot));
+
+    /* We queue directly, avoiding hidden phys->machine translation. */
+    queue_l1_entry_update(__pa(pte), phys | pgprot_val(prot));
 
     /*
      * It's enough to flush this one mapping.
@@ -124,10 +126,54 @@ static inline void set_pte_phys (unsigned long vaddr,
     __flush_tlb_one(vaddr);
 }
 
+void __set_fixmap (enum fixed_addresses idx, unsigned long phys, 
+                   pgprot_t flags)
+{
+    unsigned long address = __fix_to_virt(idx);
+
+    if (idx >= __end_of_fixed_addresses) {
+        printk("Invalid __set_fixmap\n");
+        return;
+    }
+    set_pte_phys(address, phys, flags);
+}
+
+static void __init fixrange_init (unsigned long start, 
+                                  unsigned long end, pgd_t *pgd_base)
+{
+    pgd_t *pgd;
+    pmd_t *pmd;
+    pte_t *pte;
+    int i, j;
+    unsigned long vaddr;
+
+    vaddr = start;
+    i = __pgd_offset(vaddr);
+    j = __pmd_offset(vaddr);
+    pgd = pgd_base + i;
+
+    for ( ; (i < PTRS_PER_PGD) && (vaddr != end); pgd++, i++) {
+        pmd = (pmd_t *)pgd;
+        for (; (j < PTRS_PER_PMD) && (vaddr != end); pmd++, j++) {
+            if (pmd_none(*pmd)) {
+                pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE);
+                set_pmd(pmd, __pmd(_KERNPG_TABLE + __pa(pte)));
+                if (pte != pte_offset(pmd, 0))
+                    BUG();
+            }
+            vaddr += PMD_SIZE;
+        }
+        j = 0;
+    }
+
+    XENO_flush_page_update_queue();
+}
+
 void __init paging_init(void)
 {
     unsigned long zones_size[MAX_NR_ZONES] = {0, 0, 0};
     unsigned int max_dma, high, low;
+    unsigned long vaddr;
     
     max_dma = virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT;
     low = max_low_pfn;
@@ -143,6 +189,19 @@ void __init paging_init(void)
         zones_size[ZONE_NORMAL] = low - max_dma;
     }
     free_area_init(zones_size);
+
+    /*
+     * Fixed mappings, only the page table structure has to be created - 
+     * mappings will be set by set_fixmap():
+     */
+    vaddr = __fix_to_virt(__end_of_fixed_addresses - 1) & PMD_MASK;
+    fixrange_init(vaddr, 0, init_mm.pgd);
+
+    /*
+     * XXX We do this conversion early, so that all other page tables
+     * will automatically get this mapping.
+     */
+    set_fixmap(FIX_BLKRING_BASE, start_info.blk_ring);
 }
 
 
index 30764d7b7563b78d714ef4c8b18e583b8eb2e6bd..5c3d46e36be7203c40a1dddaa2f8df7d7d3677ff 100644 (file)
@@ -18,6 +18,7 @@
 #include <asm/processor.h>
 #include <asm/hypervisor.h>
 #include <linux/threads.h>
+#include <asm/fixmap.h>
 
 #ifndef _I386_BITOPS_H
 #include <asm/bitops.h>
@@ -99,7 +100,7 @@ extern void pgtable_cache_init(void);
 #define VMALLOC_START  (((unsigned long) high_memory + 2*VMALLOC_OFFSET-1) & \
                                                ~(VMALLOC_OFFSET-1))
 #define VMALLOC_VMADDR(x) ((unsigned long)(x))
-#define VMALLOC_END    (HYPERVISOR_VIRT_START-PAGE_SIZE)
+#define VMALLOC_END    (FIXADDR_START - 2*PAGE_SIZE)
 
 #define _PAGE_BIT_PRESENT      0
 #define _PAGE_BIT_RW           1